import PDFDocument from 'pdfkit';
import fs from 'fs';
import path from 'path';

// 处理签名格式化的辅助函数
const formatSignature = (signature) => {
  if (!signature) return '无';
  // 移除0x前缀
  return signature.replace(/^0x/, '');
};

// 截断以太坊地址格式化函数
const formatEthAddress = (address) => {
  if (!address) return '无';
  // 显示前6位和后4位，中间用省略号
  return `${address.slice(0, 8)}...${address.slice(-6)}`;
};

const generateGradeReport = async (data, studentInfo, outputPath = 'grade-report.pdf') => {
  // 创建一个新的PDF文档，使用更好的边距和支持中文的字体
  const doc = new PDFDocument({ 
    margin: 50,
    size: 'A4',
    layout: 'landscape', // 使用横向布局以获得更宽的表格
    info: {
      Title: '学生成绩报告',
      Author: '成绩报告系统',
    }
  });
  
  const stream = fs.createWriteStream(outputPath);
  doc.pipe(stream);
  
  // 注册字体用于支持中文
  // 注意：您需要有一个支持中文的字体文件，比如微软雅黑、思源宋体等
  // 以下为示例路径，您需要根据实际情况修改
  const fontPath = path.join(process.cwd(), 'fonts', 'dingliesongtypeface.ttf');
  doc.registerFont('ChineseFont', fontPath);
  doc.registerFont('ChineseFontBold', fontPath);
  
  // 设置文档标题
  doc.font('ChineseFontBold').fontSize(24).fillColor('#2c3e50');
  doc.text('学生成绩报告', { align: 'center' });
  doc.moveDown(0.5);
  
  // 添加报告生成时间戳
  doc.fontSize(10).fillColor('#7f8c8d');
  doc.text(`生成时间：${new Date().toLocaleString('zh-CN')}`, { align: 'center' });
  doc.moveDown(1);
  
  // 添加学生信息部分
  const studentInfoY = doc.y;
  const studentInfoBoxWidth = 500;
  const studentInfoBoxMargin = (doc.page.width - studentInfoBoxWidth) / 2;
  const studentInfoBoxHeight = 80;
  
  // 绘制学生信息背景框
  doc.roundedRect(studentInfoBoxMargin, studentInfoY, studentInfoBoxWidth, studentInfoBoxHeight, 5)
     .fillAndStroke('#f0f8ff', '#3498db');
  
  // 添加学生信息标题
  doc.font('ChineseFontBold').fontSize(14).fillColor('#2c3e50');
  doc.text('学生基本信息', studentInfoBoxMargin + 10, studentInfoY + 10);
  
  // 添加学生详细信息
  doc.font('ChineseFont').fontSize(12).fillColor('#2c3e50');
  
  // 创建两列布局
  const colWidth = (studentInfoBoxWidth - 30) / 2;
  
  // 第一列
  doc.text(`姓名: ${studentInfo.name || '未提供'}`, 
    studentInfoBoxMargin + 10, 
    studentInfoY + 35);
  
  doc.text(`学号: ${studentInfo.personnel_id || '未提供'}`, 
    studentInfoBoxMargin + 10, 
    studentInfoY + 55);
  
  // 第二列
  doc.text(`区块链地址: ${formatEthAddress(studentInfo.ethereum_address) || '未提供'}`, 
    studentInfoBoxMargin + 10 + colWidth, 
    studentInfoY + 35);
  
  // 如果有更多学生信息，可以继续在第二列添加
  doc.text(`总课程数: ${data.length}`, 
    studentInfoBoxMargin + 10 + colWidth, 
    studentInfoY + 55);
  
  doc.moveDown(2.5); // 增加移动距离，为表格留出足够空间
  
  // 定义适合A4横向布局的列 - 调整各列宽度以适应教师签名的完整显示
  const columns = [
    {
      header: '课程名称',
      key: "enrollment_course_name",
      width: 80,
      format: value => value || "未注册"
    },
    {
      header: '日常成绩',
      key: "daily_grade",
      width: 60,
      align: "center",
      format: value => `${parseFloat(value).toFixed(1)}`
    },
    {
      header: '考试成绩',
      key: "exam_grade",
      width: 60,
      align: "center",
      format: value => `${parseFloat(value).toFixed(1)}`
    },
    {
      header: '作业成绩',
      key: "homework_grade",
      width: 60,
      align: "center",
      format: value => `${parseFloat(value).toFixed(1)}`
    },
    {
      header: '最终成绩',
      key: "final_grade",
      width: 60,
      align: "center",
      style: { bold: true },
      format: value => `${parseFloat(value).toFixed(1)}`
    },
    {
      header: '教师评语',
      key: "teacher_feedback",
      width: 80,
      format: value => value ? value.replace(/(.{8})/g, "$1\n") : '无'
    },
    {
      header: '学年',
      key: "semester_name",
      width: 80,
      format: value => value || "出错"
    },
    {
      header: '最后更新',
      key: "last_updated",
      width: 80,
      format: value => value ? new Date(value).toLocaleDateString('zh-CN') : '无'
    },
    {
      header: '更新人',
      key: "updated_by",
      width: 60,
      format: value => value ? `ID: ${value}` : '无'
    },
    {
      header: '教师签名',
      key: "teacher_signature",
      width: 180,  // 稍微减少宽度
      format: value => formatSignature(value),
      wordBreak: true  // 允许单词断行
    }
  ];
  
  // 计算总宽度以居中表格
  const tableWidth = columns.reduce((sum, col) => sum + col.width, 0);
  const margin = (doc.page.width - 2 * doc.page.margins.left - tableWidth) / 2 + doc.page.margins.left;
  
  // 绘制表头和背景
  const startY = doc.y + 10;
  
  // 绘制表头背景
  doc.fillColor('#3498db').rect(margin, startY, tableWidth, 30).fill();
  
  // 绘制表头文本
  doc.fillColor('#ffffff').font('ChineseFontBold').fontSize(12);
  let xPosition = margin;
  columns.forEach(column => {
    doc.text(
      column.header, 
      xPosition + 5, 
      startY + 10,
      { width: column.width - 10, align: column.align || 'left' }
    );
    xPosition += column.width;
  });
  
  // 绘制数据行
  let y = startY + 30;
  const rowHeight = 60;
  
  data.forEach((record, rowIndex) => {
    // 交替行背景颜色
    if (rowIndex % 2 === 0) {
      doc.fillColor('#ecf0f1').rect(margin, y, tableWidth, rowHeight).fill();
    }
    
    // 绘制单元格文本
    doc.fillColor('#2c3e50').font('ChineseFont').fontSize(10);
    xPosition = margin;
    
    columns.forEach(column => {
      const value = record[column.key];
      let formattedValue = '无';
      
      if (value !== undefined && value !== null) {
        formattedValue = column.format ? column.format(value) : value;
      }
      
      // 对最终成绩应用粗体样式
      if (column.style?.bold) {
        doc.font('ChineseFontBold');
      } else {
        doc.font('ChineseFont');
      }
      
      doc.text(
        formattedValue,
        xPosition + 5,
        y + 5,
        { 
          width: column.width - 10, 
          align: column.align || 'left',
          height: rowHeight - 10,
          lineBreak: true,
          ellipsis: false  // 确保不会添加省略号
        }
      );
      xPosition += column.width;
    });
    
    y += rowHeight;
    
    // 处理分页 - 提前检查是否需要分页，留出足够空间
    if (y > doc.page.height - 70) {
      doc.addPage({ layout: 'landscape' });
      // 在新页面上绘制表头
      y = doc.page.margins.top;
      
      // 在新页面上重新绘制表头
      doc.fillColor('#3498db').rect(margin, y, tableWidth, 30).fill();
      doc.fillColor('#ffffff').font('ChineseFontBold').fontSize(12);
      
      xPosition = margin;
      columns.forEach(column => {
        doc.text(
          column.header, 
          xPosition + 5, 
          y + 10,
          { width: column.width - 10, align: column.align || 'left' }
        );
        xPosition += column.width;
      });
      
      y += 30;
    }
  });
  
  // 绘制表格边框
  doc.lineWidth(1).strokeColor('#bdc3c7');
  
  // 绘制水平线
  doc.moveTo(margin, startY).lineTo(margin + tableWidth, startY).stroke();
  doc.moveTo(margin, startY + 30).lineTo(margin + tableWidth, startY + 30).stroke();
  doc.moveTo(margin, y).lineTo(margin + tableWidth, y).stroke();
  
  // 绘制垂直线
  xPosition = margin;
  doc.moveTo(xPosition, startY).lineTo(xPosition, y).stroke();
  columns.forEach(column => {
    xPosition += column.width;
    doc.moveTo(xPosition, startY).lineTo(xPosition, y).stroke();
  });
  
  // 检查是否需要添加新页面用于统计摘要
  // 如果剩余空间不足以容纳统计摘要，则添加新页面
  if (doc.y + 200 > doc.page.height - doc.page.margins.bottom) {
    doc.addPage({ layout: 'landscape' });
  }
  
  // 检查是否需要添加新页面用于统计摘要
  // 计算需要的高度：标题 + 间隔 + 统计框高度 + 区块链地址信息 + 页脚 = 约200px
  const requiredHeight = 200;
  
  // 如果当前页剩余空间不足，则添加新页面
  if (doc.y + requiredHeight > doc.page.height - doc.page.margins.bottom) {
    doc.addPage({ layout: 'landscape' });
  }
  
  // 添加统计摘要部分
  doc.font('ChineseFontBold').fontSize(14).fillColor('#2c3e50');
  doc.text('成绩统计', { align: 'center' });
  doc.moveDown(0.5);
  
  // 计算统计数据
  const avgDailyGrade = data.reduce((sum, record) => sum + parseFloat(record.daily_grade || 0), 0) / data.length;
  const avgExamGrade = data.reduce((sum, record) => sum + parseFloat(record.exam_grade || 0), 0) / data.length;
  const avgHomeworkGrade = data.reduce((sum, record) => sum + parseFloat(record.homework_grade || 0), 0) / data.length;
  const avgFinalGrade = data.reduce((sum, record) => sum + parseFloat(record.final_grade || 0), 0) / data.length;
  
  // 找出最高和最低成绩的课程
  const highestGradeCourse = [...data].sort((a, b) => parseFloat(b.final_grade) - parseFloat(a.final_grade))[0];
  const lowestGradeCourse = [...data].sort((a, b) => parseFloat(a.final_grade) - parseFloat(b.final_grade))[0];
  
  // 绘制统计框
  const summaryBoxY = doc.y;
  const summaryBoxWidth = 500;
  const summaryBoxHeight = 150;
  const summaryBoxMargin = (doc.page.width - summaryBoxWidth) / 2;
  
  doc.roundedRect(summaryBoxMargin, summaryBoxY, summaryBoxWidth, summaryBoxHeight, 5)
     .fillAndStroke('#f9f9f9', '#bdc3c7');
  
  // 创建统计表格 - 使用两列布局
  doc.fontSize(11).font('ChineseFont');
  doc.fillColor('#2c3e50');
  
  // 左侧列
  doc.text(`平均日常成绩: ${avgDailyGrade.toFixed(2)}`, summaryBoxMargin + 20, summaryBoxY + 15);
  doc.text(`平均考试成绩: ${avgExamGrade.toFixed(2)}`, summaryBoxMargin + 20, summaryBoxY + 35);
  doc.text(`平均作业成绩: ${avgHomeworkGrade.toFixed(2)}`, summaryBoxMargin + 20, summaryBoxY + 55);
  
  // 突出显示最终成绩
  doc.font('ChineseFontBold');
  doc.text(`平均最终成绩: ${avgFinalGrade.toFixed(2)}`, summaryBoxMargin + 20, summaryBoxY + 75);
  
  // 右侧列 - 最高/最低成绩课程
  doc.font('ChineseFont');
  doc.text(`最高成绩课程: ${highestGradeCourse.enrollment_course_name}`, 
    summaryBoxMargin + 250, summaryBoxY + 15);
  doc.text(`最高成绩: ${parseFloat(highestGradeCourse.final_grade).toFixed(1)}`, 
    summaryBoxMargin + 250, summaryBoxY + 35);
  
  doc.text(`最低成绩课程: ${lowestGradeCourse.enrollment_course_name}`, 
    summaryBoxMargin + 250, summaryBoxY + 75);
  doc.text(`最低成绩: ${parseFloat(lowestGradeCourse.final_grade).toFixed(1)}`, 
    summaryBoxMargin + 250, summaryBoxY + 95);
  
  // 添加学生区块链地址验证信息
  doc.moveDown(2);
  doc.fontSize(10).fillColor('#7f8c8d').font('ChineseFont');
  doc.text(`学生区块链地址: ${studentInfo.ethereum_address || '未提供'}`, {
    align: 'center'
  });
  
  // 添加页脚
  const pageBottom = doc.page.height - doc.page.margins.bottom;
  doc.fontSize(8).fillColor('#7f8c8d').font('ChineseFont');
  doc.text('© 2025 学生成绩管理系统 - 自动生成的报告', doc.page.margins.left, pageBottom - 20, {
    align: 'center',
    width: doc.page.width - 2 * doc.page.margins.left
  });
  
  // 完成文档
  doc.end();
  
  return new Promise((resolve, reject) => {
    stream.on('finish', () => resolve(outputPath));
    stream.on('error', reject);
  });
};

// 从JSON文件加载数据的函数
const loadDataFromFile = async (filePath) => {
  try {
    const data = await fs.promises.readFile(filePath, 'utf8');
    return JSON.parse(data);
  } catch (error) {
    throw new Error(`加载数据失败: ${error.message}`);
  }
};

export default generateGradeReport;